﻿using System;
using System.ServiceModel;
using System.Diagnostics;
using Rio.Framework.RioManager;
using Rio.Workflow.Runtime;
using System.Threading;

namespace Rio.Workflow.WCF.Configuration
{
    public static class ServiceManager
    {
        private static ServiceHost _host;
        private static Thread _threadHoster;
        private static readonly WorkflowEngine _runtime;

        /// <summary>
        /// Gets the runtime.
        /// </summary>
        public static WorkflowEngine Runtime
        {
            get
            {
                return _runtime;
            }
        }

        /// <summary>
        /// Initializes the <see cref="ServiceManager"/> class.
        /// </summary>
        static ServiceManager()
        {
            _runtime = new WorkflowEngine();
            try
            {
                if (!SettingsManager.Init())
                {
                    throw new Exception("Service manager - Load Settings error!");
                }
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry("RioWorkflowService", "ServiceManager init error " + ex.Message, EventLogEntryType.Error);
                throw new Exception("ServiceManager init error " + ex.Message, ex);
            }
        }

        /// <summary>
        /// Startup service
        /// </summary>
        public static void StartService()
        {
            //host wcf service
            _threadHoster = new Thread(HostService) {IsBackground = true, Priority = ThreadPriority.AboveNormal};
            _threadHoster.Start();
            _runtime.StartRuntime();
        }

        /// <summary>
        /// Startup service
        /// </summary>
        public static void StartServiceForWebHosting()
        {
            _runtime.StartRuntime();
        }

        /// <summary>
        /// Shutdown service
        /// </summary>
        public static void Shutdown()
        {
            try
            {
                if (_host != null)
                    _host.Close();

                if (_threadHoster != null)
                    _threadHoster.Abort();
                _runtime.StopRuntime();

            }
            catch (Exception ex)
            {
                LoggerManager.GetBusinessLogger.LogError("Shutdown error " + ex.Message);
            }
        }

        /// <summary>
        /// Hosting service
        /// </summary>
        /// <returns></returns>
        private static void HostService()
        {
            try
            {
                _host = new ServiceHost(typeof(RioWCFWorkflow));
                _host.Faulted += host_Faulted;

                //-- open host
                if (_host.State != CommunicationState.Opened | _host.State != CommunicationState.Opening)
                    _host.Open();
            }
            catch (CommunicationObjectFaultedException ex)
            {
                LoggerManager.GetBusinessLogger.LogError("HostService Bad Communication Exception " + ex.Message);
                throw;
            }
            catch (TimeoutException ex)
            {
                LoggerManager.GetBusinessLogger.LogError("HostService Timeout Exception " + ex.Message);
                throw;
            }
            catch (Exception ex)
            {
                LoggerManager.GetBusinessLogger.LogError("HostService error " + ex.Message);
                throw;
            }
        }

        /// <summary>
        /// Host in faulted state
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void host_Faulted(object sender, EventArgs e)
        {
            EventLog.WriteEntry("RioWorkflowService", "Host is in faulted state", EventLogEntryType.Error);
            LoggerManager.GetBusinessLogger.LogError("Host is in faulted state");
            _host.Abort();
        }
    }
}